!!!###!!!title=100- VChart 中 Tooltip 如何实现多列显示?——VisActor/VChart FAQ 文档!!!###!!!

VChart 中 Tooltip 如何实现多列显示?

问题描述

类似 (https://visactor.io/vchart/demo/tooltip/format-method?keyword=tooltip)这样的图表,希望tooltip能格式化成多列

解决方案

不同图表库的解决方案不一样,根据你给的 demo,在 VChart 中需要通过自定义 tooltip 的功能自行实现 tooltip 的多列样式。

代码示例

const data = [
  { year: '2012', type: 'Forest', value: 320 },
  { year: '2012', type: 'Steppe', value: 220 },
  { year: '2012', type: 'Desert', value: 150 },
  { year: '2012', type: 'Wetland', value: 98 },
  { year: '2013', type: 'Forest', value: 332 },
  { year: '2013', type: 'Steppe', value: 182 },
  { year: '2013', type: 'Desert', value: 232 },
  { year: '2013', type: 'Wetland', value: 77 },
  { year: '2014', type: 'Forest', value: 301 },
  { year: '2014', type: 'Steppe', value: 191 },
  { year: '2014', type: 'Desert', value: 201 },
  { year: '2014', type: 'Wetland', value: 101 },
  { year: '2015', type: 'Forest', value: 334 },
  { year: '2015', type: 'Steppe', value: 234 },
  { year: '2015', type: 'Desert', value: 154 },
  { year: '2015', type: 'Wetland', value: 99 },
  { year: '2016', type: 'Forest', value: 390 },
  { year: '2016', type: 'Steppe', value: 290 },
  { year: '2016', type: 'Desert', value: 190 },
  { year: '2016', type: 'Wetland', value: 40 }
];
const aggregation = {};
data.forEach(({ year, value }) => {
  if (!aggregation[year]) {
    aggregation[year] = 0;
  }
  aggregation[year] += value;
});
const spec = {
  type: 'bar',
  data: [
    {
      id: 'bar',
      values: data
    }
  ],
  xField: ['year', 'type'],
  yField: 'value',
  seriesField: 'type',
  bar: {
    state: {
      legend_hover_reverse: {
        fill: '#ccc'
      }
    }
  },
  legends: {
    visible: true
  },
  tooltip: {
    mark: {
      title: {
        value: datum => datum['year'] + '年'
      },
      content: [
        {
          key: datum => datum['type'],
          value: datum => datum['value']
        },
        {
          hasShape: false,
          key: 'Proportion',
          value: datum => Math.round((datum['value'] / aggregation[datum['year']]) * 10000) / 100 + '%'
        }
      ]
    },
    dimension: {
      title: {
        value: datum => datum['year'] + '年'
      },
      content: [
        {
          key: datum => datum['type'],
          value: datum => datum['value']
        },
        {
          hasShape: false,
          key: datum => datum['type'] + ' Proportion',
          value: datum => Math.round((datum['value'] / aggregation[datum['year']]) * 10000) / 100 + '%'
        }
      ]
    }
  }
};

const vchart = new VChart(spec, { dom: CONTAINER_ID });
vchart.renderSync();

vchart.setTooltipHandler({
  showTooltip: (activeType, tooltipData, params) => {
    // some code of custom tooltip
    let tooltip = document.getElementById('custom-tooltip');
    console.log(params);
    if (!tooltip) {
      tooltip = document.createElement('div');
      tooltip.id = 'custom-tooltip';
      document.getElementById(CONTAINER_ID).appendChild(tooltip);
      const title = document.createElement('p');
      title.id = 'custom-tooltip-title';
      title.style['fontWeight'] = 'bolder';
      tooltip.appendChild(title);
      const content = document.createElement('div');
      content.id = 'custom-tooltip-content';
      content.style.display = 'flex';
      content.style.flexDirection = 'row';
      tooltip.appendChild(content);
      const leftC = document.createElement('div');
      leftC.style.display = 'flex';
      leftC.style.flexDirection = 'column';
      leftC.style.justifyContent = 'center';
      const s = document.createElement('div');
      s.id = 'custom-tooltip-symbol';
      s.style.width = '10px';
      s.style.height = '10px';
      leftC.appendChild(s);
      const rightC = document.createElement('div');
      rightC.style.width = '200px';
      rightC.style.display = 'flex';
      rightC.style.justifyContent = 'space-around';
      content.appendChild(leftC);
      content.appendChild(rightC);
      const r1 = document.createElement('div');
      r1.id = 'custom-tooltip-r1';
      const r2 = document.createElement('div');
      r2.id = 'custom-tooltip-r2';
      const r3 = document.createElement('div');
      r3.id = 'custom-tooltip-r3';
      r3.style.color = 'grey';
      rightC.appendChild(r1);
      rightC.appendChild(r2);
      rightC.appendChild(r3);
    }

    if (!tooltip || activeType !== 'mark') return;
    const datum = tooltipData[0].datum[0];
    const series = tooltipData[0].series;
    console.log(activeType, tooltipData, params, datum);
    tooltip.style.visibility = 'visible';
    tooltip.style.left = params.event.x + 20 + 'px';
    tooltip.style.top = params.event.y + 20 + 'px';
    tooltip.style.position = 'absolute';
    tooltip.style.background = 'white';
    tooltip.style.padding = '10px';
    const title = document.getElementById('custom-tooltip-title');
    title.innerText = datum['year'] + '年';
    const s = document.getElementById('custom-tooltip-symbol');
    s.style.background = series.getSeriesStyle(datum)('fill');
    const r1 = document.getElementById('custom-tooltip-r1');
    const r2 = document.getElementById('custom-tooltip-r2');
    const r3 = document.getElementById('custom-tooltip-r3');
    r1.innerText = datum['type'];
    r2.innerText = Math.round((datum['value'] / aggregation[datum['year']]) * 10000) / 100 + '%';
    r3.innerText = datum['value'];
  },
  hideTooltip: () => {
    // hide your custom tooltip
    const tooltip = document.getElementById('custom-tooltip');
    if (!tooltip) return;
    tooltip.style.visibility = 'hidden';
  }
});

// Just for the convenience of console debugging, DO NOT COPY!
window['vchart'] = vchart;

结果展示

在线效果参考:https://codesandbox.io/s/tooltip-multicolumn-j9s8x7

相关文档

Tooltip 教程:https://visactor.io/vchart/guide/tutorial_docs/Chart_Concepts/Tooltip 相关 api:https://visactor.io/vchart/option/barChart#tooltip.visible github:https://github.com/VisActor/VChart